﻿namespace LiSA_Server.Base.Factories
{
    using System;
    using System.Collections.Concurrent;
    using AbstractActioners;

    public class ActionerFactory : IActionerFactory
    {
        private ActionerFactory()
        {
        }

        private static IActionerFactory instance;

        public static IActionerFactory Instance
        {
            get
            {
                if (instance == null)
                {
                    instance = new ActionerFactory();
                }

                return instance;
            }
        }

        private ConcurrentDictionary<Type, Object> instantiatedActioners;

        private ConcurrentDictionary<Type, Object> InstantiatedActioners
        {
            get
            {
                if (this.instantiatedActioners == null)
                {
                    this.instantiatedActioners = new ConcurrentDictionary<Type, object>();
                }

                return this.instantiatedActioners;
            }
        }

        public T Get<T>() where T : BaseActioner, new()
        {
            if (this.InstantiatedActioners.ContainsKey(typeof(T)))
            {
                return this.InstantiatedActioners[typeof(T)] as T;
            }

            var ret = new T();

            this.InstantiatedActioners.GetOrAdd(typeof(T), ret);

            return ret;
        }

        /// <summary>
        /// Method used for injecting a new (temporary) factory. Mostly for testing purposes.
        /// </summary>
        /// <param name="newFactory">the new factory</param>
        public static void Inject(IActionerFactory newFactory)
        {
            instance = newFactory;
        }
    }
}
